
#include "chessboard.h"
#include "chesspane.h"
#include "nodehead.h"
#include "stdlib.h"
#include <iostream>

using std::cout;
using std::endl;

ChessBoard::ChessBoard(int n): _paneNumber(n), _paneCount(0)
{
    orders.clear();
    lastPane = NULL;
    lastPane2 = NULL;
    secondHandColor = WHITECHESS;
    vector<ChessPane*> cgrid(_paneNumber, NULL);
    paneGrid = vector<vector<ChessPane*> >(_paneNumber, cgrid);

    Vector1 sgrid(_paneNumber, BLANKPLACE);
    signGrid = Vector2(_paneNumber, sgrid);
}

void ChessBoard::cleanUp()
{
    // paneGrid保存着棋子的指针，需要析构
    vector<ChessPane*>::iterator j;
    vector<vector<ChessPane*> >::iterator i;
    for (i = paneGrid.begin(); i != paneGrid.end(); i ++)
        for (j = i->begin(); j != i->end(); j ++){
            if (*j != NULL) delete *j;
            *j = NULL;
        }
    // signGrid 的内容太简单了。直接抛弃。
    signGrid.clear();
    Vector1 sgrid(_paneNumber, BLANKPLACE);
    signGrid = Vector2(_paneNumber, sgrid);
    
    orders.clear();
    lastPane = NULL;
    lastPane2 = NULL;
}

bool ChessBoard::scanBoard()
{
    int count;
    if (lastPane == NULL)
        return false;
    //计算某两个相对方向上相同棋子数,相加,4次循环，8个方向
    //1 左上, 9 - 1 = 8 右下
    for (int i = 1; i < 5; i++) {
        count = lastPane->CheckStart(i) + lastPane->CheckStart(9 - i);
        //新棋子按两个方向递归,自己加了两次
        if (count >= 6)
            return true;
    }
    return false;
}

bool ChessBoard::getBestPlace(int& x, int& y)
{
    if (lastPane == NULL) { // 先手，出子在中间随机位置
        x = _paneNumber / 2 + rand() * 100 % 3 - 1;
        y = _paneNumber / 2 + rand() * 100 % 3 - 1;
        return true;
    }
    //根据刚下的棋子，建立一个判断树
    NodeHead head(lastPane);
    x = head.bestm;
    y = head.bestn;
    return true;
}

bool ChessBoard::saveChess(int x, int y)
{
    ChessPane* pane;
    // 判断是否可落子
    if (signGrid[x][y] != BLANKPLACE)
        return false;

    // 处理棋子颜色
    char type = secondHandColor;
    if (lastPane != NULL)
        type = lastPane->color;

    // 与上次的棋子的颜色相反。
    if (type == BLACKCHESS)
        pane = new WhitePane(x, y, this);
    else
        pane = new BlackPane(x, y, this);
    paneGrid[x][y] = pane;                // save chess link
    signGrid[x][y] = pane->color;         // sign to the grid
    orders.push_back(x*_paneNumber + y);     // push (x,y) to orders
    _paneCount ++;
    lastPane2 = lastPane;
    lastPane = pane;
    return true;
}


bool ChessBoard::undo()
{
    if (orders.size() == 0)
        return false;
    // 计算上一步的位置
    unsigned long value = orders.back();
    orders.pop_back();
    int x = value / _paneNumber;
    int y = value % _paneNumber;

    // 抹去其痕迹
    cout << " :: erase (" << x << "," << y << ")" << endl;
    signGrid[x][y] = BLANKPLACE;
    ChessPane* pane = paneGrid[x][y];
    paneGrid[x][y] = NULL;
    delete pane;
    
    // 重新设置最后的落子
    lastPane = lastPane2;
    if(orders.size() < 2)
        lastPane2 = NULL;
    else{
        value = orders.at(orders.size() - 2);
        x = value / _paneNumber;
        y = value % _paneNumber;
        lastPane2 = paneGrid[x][y];
    }
    return true;
}


void ChessBoard::showBoard()
{
    const int n = _paneNumber;
    int i, j;

    // headline
    cout << "  ";
    for (i = 0; i < n; i ++)
        cout << i % 10 << " ";
    cout << endl;

    // chess board
    for (i = 0; i < n; i ++) {
        cout << i % 10 << " ";
        for (j = 0; j < n; j ++)
            cout << signGrid[i][j] << " " ;
        cout << endl;
    }
}

